
#pragma once

#include <time.h>

#include "qtypes.h"
#include "qstring.h"


namespace micro
{
namespace utils
{



class QTimeSpan
{
public:
    QTimeSpan() throw();
    QTimeSpan( time_t time ) throw();
    QTimeSpan( LONG lDays, int nHours, int nMins, int nSecs ) throw();
    
    LONGLONG GetDays() const throw();
    LONGLONG GetTotalHours() const throw();
    LONG GetHours() const throw();
    LONGLONG GetTotalMinutes() const throw();
    LONG GetMinutes() const throw();
    LONGLONG GetTotalSeconds() const throw();
    LONG GetSeconds() const throw();
    
    time_t  GetTimeSpan() const throw();
    
    QTimeSpan operator+( QTimeSpan span ) const throw();
    QTimeSpan operator-( QTimeSpan span ) const throw();
    QTimeSpan& operator+=( QTimeSpan span ) throw();
    QTimeSpan& operator-=( QTimeSpan span ) throw();
    bool operator==( QTimeSpan span ) const throw();
    bool operator!=( QTimeSpan span ) const throw();
    bool operator<( QTimeSpan span ) const throw();
    bool operator>( QTimeSpan span ) const throw();
    bool operator<=( QTimeSpan span ) const throw();
    bool operator>=( QTimeSpan span ) const throw();
    
public:
    QString Format( LPCTSTR pszFormat ) const;
    QString Format( UINT nID ) const;
    
    
    // for compatibility with MFC 3.x
    QString Format( LPCSTR pFormat ) const;
    
    
    
    
private:
    time_t m_timeSpan;
};

class QTime
{
private:
	time_t m_time;

public:
    static QTime GetCurrentTime() throw();
    static BOOL  IsValidFILETIME( const FILETIME& ft ) throw();
    static void  ConvertTimeToString( const FILETIME& ft, QString& str,   bool includeTime = false, bool includeSeconds = false );
    static void  ConvertTimeToString( const time_t time, QString& str,   bool includeTime = false, bool includeSeconds = false );
    
    static void  TimetToFileTime( const time_t t, FILETIME& ft );
    static void  FileTimeToTimet( const FILETIME& ft, time_t& time );
    static void  DosTimeToTimet( const unsigned int tim, time_t& time );
    static void  SystemTimeToTimet( const SYSTEMTIME* pTime, time_t& tim );
    
    
    QTime() throw();
    QTime( time_t time ) throw();
    
    QTime( int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, int nDST = -1 );
    QTime( WORD wDosDate, WORD wDosTime, int nDST = -1 );
    QTime( const SYSTEMTIME& st, int nDST = -1 );
    QTime( const FILETIME& ft, int nDST = -1 );
    
    
    QTime& operator=( time_t time ) throw();
    
    
    QTime& operator+=( QTimeSpan span ) throw();
    QTime& operator-=( QTimeSpan span ) throw();
    
    QTimeSpan operator-( QTime time ) const throw();
    QTime operator-( QTimeSpan span ) const throw();
    QTime operator+( QTimeSpan span ) const throw();
    
    
    
    
    
    bool operator!=( const QTime& time ) const throw()
    {
        return m_time != time.m_time;
    }
    
    bool operator==( const QTime& time ) const throw()
    {
        return m_time == time.m_time;
    }
    
    bool operator<( const QTime& time ) const throw()
    {
        return ( m_time < time.m_time );
    }
    
    bool operator>( const QTime& time ) const throw()
    {
        return ( m_time > time.m_time );
    }
    
    bool operator<=( const QTime time ) const throw()
    {
        return ( m_time <= time.m_time );
    }
    bool operator>=( const QTime time ) const throw()
    {
        return ( m_time >= time.m_time );
    }
    
    
    
    operator time_t( ) const throw()
    {
        return ( m_time );
    }
    time_t GetTime() const throw()
    {
        return m_time;
    }
    
    
    
    struct tm* GetGmtTm( struct tm* ptm ) const;
    struct tm* GetLocalTm( struct tm* ptm ) const;
    
    
    bool GetAsSystemTime( SYSTEMTIME& st ) const throw();
    
    bool IsLeapYear()
    {
        int year = GetYear();
        return ( year % 4 ) == 0 && ( ( year % 100 ) != 0 || ( year % 400 ) == 0 );
    }
    
    
    int GetYear() const throw();
    int GetMonth() const throw()
    {
        struct tm   tm1;
        _localtime64_s( &tm1, &m_time );
        return tm1.tm_mon;
    }
    
    int GetDay() const throw();
    int GetHour() const throw();
    int GetMinute() const throw();
    int GetSecond() const throw();
    int GetDayOfWeek() const throw();
    
    // formatting using "C" strftime
    QString Format( LPCTSTR pszFormat ) const;

};

class QFileTimeSpan
{
public:
    QFileTimeSpan() throw();
    QFileTimeSpan( const QFileTimeSpan& span ) throw();
    QFileTimeSpan( LONGLONG nSpan ) throw();
    
    QFileTimeSpan& operator=( const QFileTimeSpan& span ) throw();
    
    QFileTimeSpan& operator+=( QFileTimeSpan span ) throw();
    QFileTimeSpan& operator-=( QFileTimeSpan span ) throw();
    
    QFileTimeSpan operator+( QFileTimeSpan span ) const throw();
    QFileTimeSpan operator-( QFileTimeSpan span ) const throw();
    
    bool operator==( QFileTimeSpan span ) const throw();
    bool operator!=( QFileTimeSpan span ) const throw();
    bool operator<( QFileTimeSpan span ) const throw();
    bool operator>( QFileTimeSpan span ) const throw();
    bool operator<=( QFileTimeSpan span ) const throw();
    bool operator>=( QFileTimeSpan span ) const throw();
    
    LONGLONG GetTimeSpan() const throw();
    void SetTimeSpan( LONGLONG nSpan ) throw();
    
protected:
    LONGLONG m_nSpan;
};

class QFileTime : public FILETIME
{
public:
    QFileTime() throw();
    QFileTime( const FILETIME& ft ) throw();
    QFileTime( ULONGLONG nTime ) throw();
    
    static QFileTime WINAPI GetCurrentTime() throw();
    
    QFileTime& operator=( const FILETIME& ft ) throw();
    
    QFileTime& operator+=( QFileTimeSpan span ) throw();
    QFileTime& operator-=( QFileTimeSpan span ) throw();
    
    QFileTime operator+( QFileTimeSpan span ) const throw();
    QFileTime operator-( QFileTimeSpan span ) const throw();
    QFileTimeSpan operator-( QFileTime ft ) const throw();
    
    bool operator==( QFileTime ft ) const throw();
    bool operator!=( QFileTime ft ) const throw();
    bool operator<( QFileTime ft ) const throw();
    bool operator>( QFileTime ft ) const throw();
    bool operator<=( QFileTime ft ) const throw();
    bool operator>=( QFileTime ft ) const throw();
    
    ULONGLONG GetTime() const throw();
    void SetTime( ULONGLONG nTime ) throw();
    
    QFileTime UTCToLocal() const throw();
    QFileTime LocalToUTC() const throw();
    
    static const ULONGLONG Millisecond = 10000;
    static const ULONGLONG Second = Millisecond* static_cast<ULONGLONG>( 1000 );
    static const ULONGLONG Minute = Second* static_cast<ULONGLONG>( 60 );
    static const ULONGLONG Hour = Minute* static_cast<ULONGLONG>( 60 );
    static const ULONGLONG Day = Hour* static_cast<ULONGLONG>( 24 );
    static const ULONGLONG Week = Day* static_cast<ULONGLONG>( 7 );
};









}
}//micro




